home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / scrasm / sprite.inc < prev   
Encoding:
Text File  |  1993-03-08  |  10.3 KB  |  280 lines

  1. ; SPRITE routines
  2. MAX_SPRITE      EQU     100
  3.  
  4. RECTANGLE STRUCT 2,NONUNIQUE
  5.                 X       WORD    0
  6.                 Y       WORD    0
  7.                 Wid4    BYTE    0
  8.                 Ht      BYTE    0
  9.                 Color   BYTE    0
  10.                 Next    WORD    0
  11.         ; DrawMe is used to not bother with sprites that you know
  12.         ; are contained totally within another, allowing animated
  13.         ; eyes, etc to be stored in separate sprites.  These will be
  14.         ; drawn to the local buffer but skipped when copying to the
  15.         ; screen, so if they are not TOTALLY contained, they will
  16.         ; just get clipped away.
  17.                 DrawMe  BYTE    1       ; default, yes draw me.
  18.         ; (Storage from this point on ... NEVER provide anything but
  19.         ; default for these values!)
  20.                 address_virt    WORD    0
  21.                 address_buf     WORD    0
  22.                 next_line_virt  WORD    0
  23.                 next_line_buf   WORD    0
  24. RECTANGLE ENDS
  25.  
  26. SPRITE  STRUCT 2, NONUNIQUE
  27.         RECTANGLE       <>      ; Contains rectangle info
  28. SPRITE  ENDS
  29.  
  30. EVEN
  31. rect5   SPRITE  <<40 ,60 , 2,8, C_TRANSPARENT, 0           , 0>>
  32. rect4   SPRITE  <<80 ,30 , 2,8, C_TRANSPARENT, offset rect5, 0>>
  33. rect3   SPRITE  <<120,60 , 2,8, C_TRANSPARENT, offset rect4, 0>>
  34. rect2   SPRITE  <<55 ,100, 2,8, C_TRANSPARENT, offset rect3, 0>>
  35. rect1   SPRITE  <<105,100, 2,8, C_TRANSPARENT, offset rect2, 0>>
  36.  
  37. rect6   SPRITE  <<36 ,56 , 4,16, C_BLUE, offset rect1, 1>>
  38. rect7   SPRITE  <<76 ,26 , 4,16, C_BLUE, offset rect6, 1>>
  39. rect8   SPRITE  <<116,56 , 4,16, C_BLUE, offset rect7, 1>>
  40. rect9   SPRITE  <<51 ,96 , 4,16, C_BLUE, offset rect8, 1>>
  41. rect10  SPRITE  <<101,96 , 4,16, C_BLUE, offset rect9, 1>>
  42.  
  43. ;; Simply adding in these 5 rectangles (~20000 pixels for both
  44. ;; drawing and erasing) really slows things down!  That's why
  45. ;; it's important to optimize the sprite drawing routines!
  46. rect11  SPRITE  <<35 ,55 ,14,36, C_GREEN, offset rect10, 1>>
  47. rect12  SPRITE  <<75 ,25 ,14,36, C_GREEN, offset rect11, 1>>
  48. rect13  SPRITE  <<115,55 ,14,36, C_GREEN, offset rect12, 1>>
  49. rect14  SPRITE  <<50 ,95 ,14,36, C_GREEN, offset rect13, 1>>
  50. rect15  SPRITE  <<100,95 ,14,36, C_GREEN, offset rect14, 1>>
  51.  
  52. FIRST_SPRITE    EQU     rect10
  53.  
  54. EVEN
  55. AnimateSprites  PROC    near
  56.                 ret
  57.         ; Blank out the draw page, by copying from the blank page
  58.         ; to the draw page all rectangles which had changed.  The
  59.         ; blank page must always be entirely blank if this is going
  60.         ; to work!
  61.                 mov     di,cs:DrawPage.UpperLeftAddress
  62.                 add     di,cs:DrawPage.ScrollOffset
  63.                 mov     si,cs:BlankPage.UpperLeftAddress
  64.                 add     si,cs:BlankPage.ScrollOffset
  65.                 mov     bp,cs:BlankPage.Rectangles
  66.                 call    CopyRectangles
  67.  
  68.         ; Now draw the sprites.  Uses a temporary buffer to ensure
  69.         ; minimal drawing to the screen, but that's not really necessary,
  70.         ; if memory is at a minimum.  It's just faster...
  71.                 mov     bp,offset FIRST_SPRITE
  72.                 mov     cs:DrawPage.Rectangles,bp
  73.                 call    do_fill_buffer
  74.                 mov     di,cs:DrawPage.UpperLeftAddress
  75.                 add     di,cs:DrawPage.ScrollOffset
  76.                 mov     bh,cs:DrawPage.AlignmentMask
  77.                 mov     bp,offset FIRST_SPRITE
  78.                 jmp     smart_rects     ; "call"
  79. AnimateSprites  ENDP
  80.  
  81. smart_dest      DW      0
  82. out_di          DW      0
  83. out_si          DW      0
  84.  
  85. EVEN
  86. smart_rects     PROC    near
  87.                 add     di,cs:DrawPage.Address
  88.                 mov     ds,cs:segBuffer
  89.                 mov     es,cs:segVideo
  90.                 mov     dx,3c4h
  91.                 mov     al,02h
  92.                 out     dx,al
  93.                 inc     dx
  94.                 mov     cs:smart_dest,di
  95.  
  96.         ; === Beginning of loop through rectangles! ===
  97. sp_nextrect:
  98.                 cmp     cs:[bp].RECTANGLE.DrawMe,1
  99.                 jne     sp_next
  100.         ; Draw this rectangle from the buffer to screen memory.
  101.         ; Calculate the output address.
  102.                 mov     si,cs:[bp].RECTANGLE.address_buf
  103.                 mov     di,cs:[bp].RECTANGLE.address_virt
  104.                 add     di,cs:smart_dest
  105.  
  106.         ; Loop over 4 planes
  107.                 mov     bl,4
  108. sp_plane_loop:  mov     al,bh
  109.                 out     dx,al
  110.  
  111.                 mov     cs:out_di,di
  112.                 mov     cs:out_si,si
  113.  
  114.         ; Loop over height
  115.                 mov     ch,cs:[bp].RECTANGLE.Ht
  116. sp_row_loop:
  117.  
  118.         ; Loop over width of rectangle (Wid4 is actually width/4)
  119.                 mov     cl,cs:[bp].RECTANGLE.Wid4
  120. sp_col_loop:
  121.  
  122.         ; Read a byte from the buffer
  123.         ; Is it transparent (no-modify)?  If so, just jump over the draw
  124.                 mov     al,byte ptr ds:[si]
  125.                 cmp     al,C_TRANSPARENT
  126.                 je      sp_next_pixel
  127.         ; Otherwise, draw it on the spreen, and mark it transparent
  128.         ; so that it won't be drawn again.
  129.                 mov     byte ptr es:[di],al
  130.                 mov     byte ptr ds:[si],C_TRANSPARENT
  131.  
  132.         ; Skip to next 4-byte group (next column that can be drawn in
  133.         ; Mode X)  Also increment spreen draw address, but only by 1
  134.         ; because ModeX is 4 pixels per byte
  135. sp_next_pixel:
  136.                 add     si,4
  137.                 inc     di
  138.  
  139.                 dec     cl
  140.                 jnz     sp_col_loop
  141.  
  142.         ; End of row.  Skip space to get to left edge of next row down
  143.         ;  Skip SI = (SCREEN_WIDTH - #bytesdrawn)
  144.         ; Only draw up to height of rectangle
  145.                 add     si,cs:[bp].RECTANGLE.next_line_buf
  146.                 add     di,cs:[bp].RECTANGLE.next_line_virt
  147.                 dec     ch
  148.                 jnz     sp_row_loop
  149.  
  150.                 mov     di,cs:out_di
  151.                 mov     si,cs:out_si
  152.                 inc     si
  153.                 rol     bh,1
  154.                 adc     di,0
  155.  
  156.                 dec     bl
  157.                 jnz     sp_plane_loop
  158.  
  159.         ; Follow chain to next rectangle
  160. sp_next:        mov     bp,cs:[bp].RECTANGLE.Next
  161.                 cmp     bp,0
  162.                 jne     sp_nextrect
  163.         ; All done
  164. sp_end:         ret
  165. smart_rects     ENDP
  166.  
  167. ; BP -> first rectangle.  Follows BP->next, stops when BP = 0
  168. EVEN
  169. do_fill_buffer  PROC    near
  170.                 mov     es,cs:segBuffer
  171.  
  172.                 cmp     bp,0
  173.                 je      fill_end
  174. fill_loop:
  175.  
  176.                 mov     bx,cs:[bp].RECTANGLE.Y
  177.                 shl     bx,1                    ; BX = word index y
  178.                 mov     di,cs:MultBufWidth[bx]  ; DI = SW * y
  179.                 mov     cx,cs:[bp].RECTANGLE.X  ; CX = x
  180.                 add     di,cx                   ; DI = (SW * y) + x
  181.                 mov     cs:[bp].RECTANGLE.address_buf,di ; (DI used later)
  182.  
  183.                 mov     ax,cs:MultVirtWidth[bx] ; AX = (VW/4) * y
  184.                 shr     cx,2                    ; CX = (x / 4)
  185.                 add     ax,cx                   ; AX = (VW * y + x)/4
  186.                 mov     cs:[bp].RECTANGLE.address_virt,ax
  187.  
  188.                 mov     dx,(VIRTUAL_WIDTH / 4)
  189.                 sub     dl,cs:[bp].RECTANGLE.Wid4 ; DX = (VW - w) / 4
  190.                 mov     cs:[bp].RECTANGLE.next_line_virt,dx
  191.  
  192.                 mov     dx,(SCREEN_WIDTH / 4)
  193.                 sub     dl,cs:[bp].RECTANGLE.Wid4 ; DX = (SW - w) / 4
  194.                 shl     dx,2                      ; DX = SW - w
  195.                 mov     cs:[bp].RECTANGLE.next_line_buf,dx
  196.  
  197.                 mov     ah,cs:[bp].RECTANGLE.Color
  198.                 mov     al,cs:[bp].RECTANGLE.Color
  199.  
  200.                 mov     ch,cs:[bp].RECTANGLE.Ht
  201. fill_row_loop:  mov     cl,cs:[bp].RECTANGLE.Wid4
  202. fill_col_loop:  mov     es:[di],ax
  203.                 mov     es:[di+2],ax
  204.                 add     di,4
  205.                 dec     cl
  206.                 jnz     fill_col_loop
  207.                 add     di,dx
  208.                 dec     ch
  209.                 jnz     fill_row_loop
  210.  
  211.                 mov     bp,cs:[bp].RECTANGLE.Next
  212.                 cmp     bp,0
  213.                 jne     fill_loop
  214. fill_end:       ret
  215. do_fill_buffer  ENDP
  216.  
  217. EVEN
  218. CopyRectangles  PROC    near
  219.                 mov     ax,cs:segVideo
  220.                 mov     ds,ax
  221.                 mov     es,ax
  222.  
  223.         ; Calculate the difference between the source and destination
  224.         ; pages.  Since in a movsb loop the two would remain a constant
  225.         ; distance apart, we can just calculate a displacement and then
  226.         ; not have to worry about SI; instead use DI and DI+BX, thanks
  227.         ; to the thoughtful x86 ALU!
  228.                 mov     bx,di
  229.                 sub     bx,si
  230.  
  231.                 mov     dx,GC_INDEX
  232.                 mov     ax,ALL_COPY_BITS
  233.                 out     dx,ax
  234.  
  235.                 mov     dx,SC_INDEX
  236.                 mov     ax,0F02h
  237.                 out     dx,ax
  238.                 mov     si,di   ;store destination
  239.  
  240.         ; === Beginning of loop through rectangles! ===
  241. cr_nextrect:    cmp     cs:[bp].RECTANGLE.DrawMe,1
  242.                 jne     cr_next
  243.         ; Draw this rectangle from the buffer to screen memory.
  244.         ; Calculate the output address.
  245.                 mov     di,cs:[bp].RECTANGLE.address_virt
  246.                 mov     dx,cs:[bp].RECTANGLE.next_line_virt
  247.                 add     di,si
  248.  
  249.         ; Loop over height
  250.                 mov     ch,cs:[bp].RECTANGLE.Ht
  251. cr_row_loop:
  252.  
  253.         ; Loop over width of rectangle (Wid4 is actually width/4)
  254.                 mov     cl,cs:[bp].RECTANGLE.Wid4
  255. cr_col_loop:    mov     al,ds:[di + bx]
  256.                 stosb
  257.                 dec     cl
  258.                 jnz     cr_col_loop
  259.                 mov     al,ds:[di + bx]
  260.                 mov     es:[di],al
  261.  
  262.         ; End of row.  Skip space to get to left edge of next row down
  263.         ; Only draw up to height of rectangle
  264.                 add     di,dx
  265.                 dec     ch
  266.                 jnz     cr_row_loop
  267.  
  268.         ; Follow chain to next rectangle
  269. cr_next:        mov     bp,cs:[bp].RECTANGLE.Next
  270.                 cmp     bp,0
  271.                 jne     cr_nextrect
  272.         ; All done
  273. cr_end:
  274.                 mov     dx,GC_INDEX
  275.                 mov     ax,ALL_DRAW_BITS
  276.                 out     dx,ax
  277.                 ret
  278. CopyRectangles  ENDP
  279.  
  280.